package channel

import (
	"fmt"
	"time"
)

func RunChannel() {
	c := make(chan int, 8)
	//c <- 1
	//c <- 2
	//c <- 3
	//c <- 4
	for {
		select {
		case v, ok := <-c:
			fmt.Println(v, ok)

		}
	}

}

// 读取关闭的channel
func ReadChannelClosed() {
	c := make(chan int, 8)
	go func() {
		fmt.Println("----------------sleep-----------")
		time.Sleep(time.Duration(5) * time.Second)
		c <- 34
		close(c)
	}()
	time.Sleep(time.Duration(5) * time.Second)

	/**
	关闭的channel有数据也可以继续读

	1. go语言无法即时准确地判断channel是否关闭

	2. 从channel读取数据

	    2.1 第二个字段为true时，channel可能没关闭，也可能已经关闭，不能证明什么

	    2.2 第二个字段为false时，可以证明channel中已没有残留数据且已关闭

	3. 若channel已关闭，那么从该channel中读取数据会直接返回，且是默认值，所以一定要判断第二个字段
	*/
	v, ok := <-c

	fmt.Println(v, ok)
}

// 异步读取channel,从channel读，没有值不阻塞
func ReadChannelAsync() {

	c := make(chan int, 8)
	go func() {
		fmt.Println("----------------sleep-----------")
		time.Sleep(time.Duration(5) * time.Second)
		c <- 34
		close(c)
	}()

FOR_LOOP:
	for {
		select {
		case v, ok := <-c:
			fmt.Println("从channel取到数据", v, ok)
			break FOR_LOOP
		default:
			// 利用default不阻塞，没有default则阻塞
			fmt.Println("没有从channel,取到数据,继续等...")
			time.Sleep(time.Duration(1) * time.Second)

		}
	}

	fmt.Println("--------------结束")

}
